package p.ithorns.framework.common.mmap;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import p.ithorns.framework.common.utils.FileUtil;

import java.io.File;
import java.io.IOException;
import java.io.InputStream;
import java.io.RandomAccessFile;
import java.nio.MappedByteBuffer;
import java.nio.channels.FileChannel;

/**
 * MappedBufferWriter
 *
 * @author liuhaitao
 * @date 2024/4/7 16:58
 * @since
 */
public class MappedWriter implements MappedCleanable {

    private static final Logger log = LoggerFactory.getLogger(MappedWriter.class);

    public void write(InputStream inputStream,  File file) {
        MappedByteBuffer mappedByteBuffer = null;
        try (
                RandomAccessFile tempRaf = new RandomAccessFile(file, "rw");
        ) {
            long size = inputStream.available();
            tempRaf.setLength(size);
            FileChannel fileChannel = tempRaf.getChannel();

            mappedByteBuffer = fileChannel.map(FileChannel.MapMode.READ_WRITE, 0, fileChannel.size() * 4);
            // System.out.println("==========> map size: " + mappedByteBuffer.capacity());

            // 将 InputStream 中的数据写入 MappedByteBuffer
            byte[] buffer = new byte[4096];
            while (inputStream.read(buffer) != -1) {
                mappedByteBuffer.put(buffer);
            }

            inputStream.close();
        } catch (Exception e) {
            log.error(e.getMessage(), e);
        } finally {
            if (null != mappedByteBuffer) {
                clean(mappedByteBuffer);
            }
        }
    }

    public void write(byte[] bytes, String filePath) {
        MappedByteBuffer mappedByteBuffer = null;
        File tmpFile = FileUtil.createFile(filePath);
        try (
                RandomAccessFile tempRaf = new RandomAccessFile(tmpFile, "rw");
                FileChannel fileChannel = tempRaf.getChannel();
        ) {
            mappedByteBuffer = fileChannel.map(FileChannel.MapMode.READ_WRITE, 0, bytes.length);
            mappedByteBuffer.put(bytes);
        } catch (IOException e) {
            log.error(e.getMessage(), e);
        } finally {
            if (null != mappedByteBuffer) {
                clean(mappedByteBuffer);
            }
        }
    }

}